import os
import platform

from PySide6 import QtWidgets
from PySide6.QtCore import QObject, Signal, Qt
from PySide6.QtGui import QIcon
from PySide6.QtWidgets import QWidget, QVBoxLayout, QTreeWidget, QApplication, QTreeWidgetItem


class TreeWidgetItem:
    def __init__(self, id: any, parent_id: any, name: str, icon: QIcon = None, extend: object = None):
        """
        菜单数据接口
        :param id: ID
        :param parent_id: 父ID
        :param name: 菜单名称
        :param icon: 图标
        :param extend: 扩展数据
        """
        self.id: any = id
        self.parent_id: any = parent_id
        self.name: str = name
        self.extend: object = extend
        # 实例化
        self.treeWidgetItem = QTreeWidgetItem([self.name])
        # 存储相关数据
        self.treeWidgetItem.setData(0, Qt.UserRole + 1, extend)
        self.treeWidgetItem.setIcon(0, QIcon(':/icons/default.png'))
        if icon is not None:
            self.treeWidgetItem.setIcon(0, icon)


class ElTreeData(QObject):
    """
    Data Model
    """
    items_changed: Signal = Signal(str)
    styleSheet_changed: Signal = Signal(str)

    def __init__(self, items: list[TreeWidgetItem] = None, styleSheet: str = None):
        super(ElTreeData, self).__init__()
        # 定义数据
        self._items: list[TreeWidgetItem]
        self._styleSheet: str
        # 初始化数据
        self.items = items
        self.styleSheet = styleSheet

    @property
    def items(self):
        return self._items

    @items.setter
    def items(self, value):
        self._items = value
        # 数据改变时发出信号
        self.items_changed.emit(self.items)

    @property
    def styleSheet(self):
        return self._styleSheet

    @styleSheet.setter
    def styleSheet(self, value):
        self._styleSheet = value
        # 数据改变时发出信号
        self.styleSheet_changed.emit(self.styleSheet)


"""
初始化CSS文件位置
"""
CSS_PATH = None
if str(platform.system().lower()) == 'windows':
    path = __file__.replace(fr"\{os.path.basename(__file__)}", "").replace("\\\\", "\\")
    CSS_PATH = fr'{path}\el_tree.css'
elif str(platform.system().lower()) == 'linux':
    path = __file__.replace(fr"/{os.path.basename(__file__)}", "").replace("//", "/")
    CSS_PATH = fr'{path}/el_tree.css'
else:
    print(f"未知系统：{platform.system().lower()}")


class ElTreeUi(object):
    """
    User Interface
    """

    def setupUi(self, window):
        # with open(CSS_PATH, "r", encoding="UTF-8") as f:
        #     window.setStyleSheet(f.read())
        window.setWindowTitle("ElTree")
        # window.setWindowIcon(QIcon(':/icons/add.png'))
        window.resize(40, 30)

        # 设置整个窗体的透明度
        window.setWindowOpacity(0.90)  # 设置窗体透明度
        # 设置隐藏背景
        window.setAttribute(Qt.WA_TranslucentBackground)
        # 垂直布局
        self.layout = QVBoxLayout()
        # 设置边距为0
        self.layout.setContentsMargins(0, 0, 0, 0)
        window.setLayout(self.layout)
        self._tree = QTreeWidget()

        self._tree.setSizePolicy(QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Expanding)
        self.layout.addWidget(self._tree)


class PyElTree(QWidget, ElTreeUi):
    """
    Control
    """
    itemClicked: Signal = Signal(object)
    itemDoubleClicked: Signal = Signal(object)

    def __init__(self, treeData: ElTreeData, parent=None):
        super(PyElTree, self).__init__(parent=parent)
        self.setupUi(self)
        self.data = treeData
        self.__bind()
        # 将按钮的点击信号绑定到当前类的点击信号
        self._tree.itemClicked.connect(lambda item: self.itemClicked.emit(item.data(0, Qt.UserRole + 1)))
        self._tree.itemDoubleClicked.connect(lambda item: self.itemDoubleClicked.emit(item.data(0, Qt.UserRole + 1)))
        self.__render_items(True)

    def __render_items(self, is_clear: bool):
        if is_clear:
            self._tree.clear()
        self._tree.setColumnCount(1)
        self._tree.setHeaderHidden(True)
        if self.data.items is not None:
            # 转为字典
            mapping: dict[any, TreeWidgetItem] = dict(zip([i.id for i in self.data.items], self.data.items))
            # 树容器
            treeWidgetItems: list[QTreeWidgetItem] = []
            for d in self.data.items:
                # 如果找不到父级项，则是根节点
                parent: TreeWidgetItem = mapping.get(d.parent_id)
                if parent is None:
                    treeWidgetItems.append(d.treeWidgetItem)
                else:
                    parent.treeWidgetItem.addChild(d.treeWidgetItem)

            # 挂载到树上
            self._tree.insertTopLevelItems(0, treeWidgetItems)

    def __bind(self):
        """
        数据绑定到控件属性
        """
        pass


if __name__ == '__main__':
    """
    Test Demo
    """
    # 引入资源（这一步不能少！）
    # from images.resources_rc import *

    app = QApplication([])
    button = ElTree(ElTreeData(items=[
        TreeWidgetItem(1, 0, "User", icon=QIcon(":/icons/add.png"), extend={'id': 1}),
        TreeWidgetItem(2, 1, "Child", icon=QIcon(":/icons/address.png"), extend={'id': 2}),
        TreeWidgetItem(3, 1, "Child", icon=QIcon(":/icons/code_generator.png"), extend={'id': 3}),
        TreeWidgetItem(4, 2, "Child", icon=QIcon(":/icons/linked.png"), extend={'id': 4}),
        TreeWidgetItem(5, 2, "Child", icon=QIcon(":/icons/template.png"), extend={'id': 5}),
        TreeWidgetItem(6, 5, "Child", icon=QIcon(":/icons/template_edit.png"), extend={'id': 6}),
        TreeWidgetItem(7, 5, "Child", extend={'id': 7}),
        TreeWidgetItem(8, 5, "Child", extend={'id': 8}),
        TreeWidgetItem(9, 8, "Child", extend={'id': 9}),
    ]))

    button.itemClicked.connect(lambda extend: print("单击->扩展数据为：", extend))
    button.itemDoubleClicked.connect(lambda extend: print("双击->扩展数据为：", extend))
    button.show()
    app.exec()